﻿
using System.Diagnostics;
using System.IO.Compression;
using System.Speech.Synthesis;
using System.Text;
using System.Text.RegularExpressions;
using LitJson;
using static XMerp.Controls_Form;




namespace XMerp
{
    public static class Controller
    {
        public static View_MainForm view_MainForm { get; set; }
        public static Model model_Shop { get; set; }


        public static SpeechSynthesizer speech = new();

        private static Dictionary<string, bool> detectings = new()
        {
            { "验货",false},
            { "发货",false}
        };
        public static Dictionary<string, StringBuilder> scanners = new()
        {
            { "验货",new StringBuilder() },
            { "发货",new StringBuilder() }
        };
        public static bool hookMessage = false;
        public static bool canCheckNext = true;


        public async static void CtlFactory(string Key, params object[] Params)
        {
            switch (Key)
            {
                #region  MainForm_Event
                case "MainForm_Load":
                    view_MainForm = Params[0] as View_MainForm;
                    model_Shop = new();
                    Controls_RawInput.订阅WM_INPUT信息(view_MainForm.Handle);





                    break;
                case "MainForm_btnMutilPackage_Click":
                    if (view_MainForm.view_CheckProducts.iptMutilPack.IntValue > 0)
                    {
                        speech.SpeakAsync("请等待");
                        goto case "ApplyWaybill";
                    }
                    break;
                case "MainForm_btnMore_Click":
                    view_MainForm.RdrFactory("Render_View_Setting");
                    break;
                case "MainForm_btnWeight_Click":
                    view_MainForm.RdrFactory("Render_MainForm_btn_weight_Finish");
                    break;
                #endregion

                # region View_Setting_Event
                case "View_Setting_chkDetCheck_Click":
                    if ((bool)Params[0])
                    {
                        detectings["验货"] = true;
                    }
                    break;
                case "View_Setting_chkDetSend_Click":

                    if ((bool)Params[0])
                    {
                        detectings["发货"] = true;
                    }
                    break;
                case "View_Setting_btnDefault_Click":
                    Settings.Default.Scanner_验货 = "未设置";
                    Settings.Default.Scanner_发货 = "未设置";
                    Settings.Default.Save();
                    view_MainForm.RdrFactory("Render_View_Setting_btn_default_Finish");
                    break;
                case "View_Setting_btnCheckSave_Click":
                    Settings.Default.Scanner_验货 = (string)Params[0];
                    Settings.Default.Save();
                    break;
                case "View_Setting_btnSendSave_Click":
                    Settings.Default.Scanner_发货 = (string)Params[0];
                    Settings.Default.Save();
                    break;
                case "View_Setting_btnClose_Click":
                    view_MainForm.RdrFactory("Render_View_Setting_Dispose");
                    break;
                #endregion

                #region View_CheckProducts
                case "View_CheckProducts_btnRemarks_Click":
                    canCheckNext = true;
                    view_MainForm.RdrFactory("Render_View_CheckProducts_remarks_Finish");
                    break;
                case "View_CheckProducts_btnAdd_Click":
                    view_MainForm.RdrFactory("Render_View_CheckProducts_btn_add_Finish");
                    break;
                case "View_CheckProducts_btnLess_Click":
                    view_MainForm.RdrFactory("View_CheckProducts_btnLess_Finish");
                    break;
                #endregion





                case "RawInputData":
                    var data = Params[0] as RawInputData;
                    if (detectings["验货"])
                    {
                        view_MainForm.RdrFactory("Render_View_Setting_Detectings_Check_Finish", [data.deviceName]);
                        detectings["验货"] = false;

                    }
                    else if (detectings["发货"])
                    {
                        detectings["发货"] = false;
                        view_MainForm.RdrFactory("Render_View_Setting_Detectings_Send_Finish", [data.deviceName]);
                    }

                    if (data.deviceName == Settings.Default.Scanner_验货)
                    {
                        hookMessage = true;
                        if (data.message == "ENTER") goto case "CheckProducts";
                        else scanners["验货"].Append(data.message);
                    }
                    else if (data.deviceName == Settings.Default.Scanner_发货)
                    {
                        hookMessage = true;
                        if (data.message == "ENTER") goto case "ShipProducts";
                        else scanners["发货"].Append(data.message);
                    }
                    else
                    {
                        hookMessage = false;
                    }

                    break;
                case "SetSysWords":
                    await model_Shop.ModelFactory("SetSysWords", Params);
                    break;

                case "CheckProducts":
                    if (!canCheckNext) { speech.SpeakAsync("订单备注未确认"); return; }

                    if (view_MainForm.btnWeight.Text == "3.0") { speech.SpeakAsync("不超3公斤未确认"); return; }

                    string check_expressNo = scanners["验货"].ToString();
                    scanners["验货"].Clear();

                    var res_SearchByExpressNo = await model_Shop.ModelFactory("SearchByExpressNo", [check_expressNo]);
                    if (null == res_SearchByExpressNo) { speech.SpeakAsync("查询单号请求异常！"); return; }

                    if (res_SearchByExpressNo["message"].ToString() != "ok") { speech.SpeakAsync("查询单号请求错误！"); return; }

                    int total = (int)res_SearchByExpressNo["data"]["total"];
                    if (total == 0) { speech.SpeakAsync("单号不存在！"); return; }

                    if ((int)res_SearchByExpressNo["data"]["items"][0]["status"] == 7) { speech.SpeakAsync("订单已关闭！"); goto case "回收单号"; }

                    //缺少部分退款



                    view_MainForm.RdrFactory("Render_MainForm_CheckPorducts", [check_expressNo, res_SearchByExpressNo]);

                    break;
                case "ShipProducts":

                    string ship_expressNo = scanners["发货"].ToString();
                    scanners["发货"].Clear();
                    var res_shipByExpressNo = await model_Shop.ModelFactory("SearchByExpressNo", [ship_expressNo]);
                    if ((int)res_shipByExpressNo["data"]["items"][0]["status"] == 5) {speech.SpeakAsync("已发货"); return; }
                    else if ((int)res_shipByExpressNo["data"]["items"][0]["status"] == 7) { speech.SpeakAsync("订单已关闭"); return; }



                    var res_ShipResult = await model_Shop.ModelFactory("Send", [res_shipByExpressNo]);
                    if (null == res_ShipResult) return;

                    if (res_ShipResult["message"].ToString() == "ok") speech.SpeakAsync(ship_expressNo.ToChinese());


                    break;
                case "ApplyWaybill":
                    var waybillResult = await model_Shop.ModelFactory("ApplyWaybill", [view_MainForm.view_CheckProducts]);


                    

                    if (view_MainForm.view_CheckProducts.iptMutilPack.IntValue > 0)
                    {
                        //  await model_Shop.ModelFactory("PrintMutilPack", [waybillResult]);

                       
                        await model_Shop.WebsocketConnect();
                        string docuuments = string.Empty;
                        var obj = waybillResult["data"][0];
                        Debug.WriteLine(obj.ToJsonStr());
                        string orderPlatformCode = obj["orderPlatformCode"].ToString();
                        string templateURL = orderPlatformCode == "KHTAOBAO" ? "http://cloudprint.cainiao.com/template/standard/290659" : orderPlatformCode == "PDD" ? "https://file-link.pinduoduo.com/yto_one" : orderPlatformCode == "KS" ? "https://s2-11586.kwimgs.com/kos/nlav11586/EBST-EBSTO12.xml" : orderPlatformCode == "LUBAN" ? "" : "https://lf3-cm.ecombdstatic.com/obj/logistics-davinci/template/v2/yuantong_76_130.xml";
                        foreach (JsonData waybill in obj["waybillNoList"])
                        {
                            if (waybill.ContainsKey("errorMessage")) goto case "NoExpressNo";

                            var printData = JsonMapper.ToObject(waybill["printData"].ToString().Replace(@"/""",@""""));

                            if (docuuments.Length > 0) docuuments += ',';
                            docuuments += $@"{{""documentID"":""{waybill["waybillNo"].ToString()}"",""printData"":{{""encryptedData"":""{printData["encryptedData"].ToString()}"",""signature"":""{printData["signature"].ToString()}"",""templateURL"":""{templateURL}"",""ver"":""waybill_print_secret_version_1""}},""expressPrintType"":""CUST-CN"",""customData"":{{""printXML"":""<?xml version=\""1.0\"" encoding=\""UTF-8\""?>\n        <layout xmlns=\""http://cloudprint.cainiao.com/print\"" xmlns:xsi=\""http://www.w3.org/2001/XMLSchema-instance\"" xsi:schemaLocation=\""http://cloudprint.cainiao.com/print http://cloudprint-docs-resource.oss-cn-shanghai.aliyuncs.com/lpml_schema.xsd\"" xmlns:editor=\""http://cloudprint.cainiao.com/schema/editor\"" id=\""CUSTOM_AREA\"" width=\""70\"" height=\""40\"">\n          <layout editor:_for_=\""1592295795243879\"" id=\""1592295795243970\"" width=\""70\"" left=\""1.05\"" top=\""1.21\""  style=\""zIndex:1;\""> <text style=\""fontFamily:SimHei;fontSize:10;align:undefined;fontWeight:no;fontItatlic:false;\""><![CDATA[------------]]></text></layout></layout>""}},""addData"":{{""sender"":{{""address"":{{""detail"":""东望北街2号"",""city"":""辽宁省沈阳市"",""district"":""大东区"",""province"":"""",""town"":""""}},""mobile"":""*******4060"",""name"":""小楠婚庆"",""phone"":""""}}}}}}";
                        }
                        string send = $@"{{""cmd"":""print"",""printer"":""HPRT N31BT"",""taskId"":""task|{obj["id"].ToString()}"",""firstDocumentNumber"":1,""totalDocumentCount"":{obj["waybillNoList"].Count},""documents"":[{docuuments}]}}";

                        Debug.WriteLine(send);
                        await model_Shop.WebsocketSend(send);
                        await model_Shop.WebsocketClose();

                        view_MainForm.RdrFactory("Render_MainForm_expressNo_Finish");
                    }      
                    break;

                case "回收单号":
                    
                    //
                    speech.SpeakAsync("单号回收成功");
                    return;
                case "NoExpressNo":
                    speech.SpeakAsync("电子面单账户余额不足");
                    break;

            }
        }






    }
    public static class Extend
    {
        public static string ToJsonStr(this JsonData jsonObj)
        {
            string jsonStr = jsonObj.ToJson();
            Regex reg = new Regex(@"(?i)\\[uU]([0-9a-f]{4})");
            return reg.Replace(jsonStr, delegate (Match m) { return ((char)Convert.ToInt32(m.Groups[1].Value, 16)).ToString(); });
        }

        public static async Task<Image> ToImage(this string url)
        {
            using (HttpClient client = new HttpClient() { Timeout = TimeSpan.FromSeconds(30) })
            {
                return Image.FromStream(await client.GetStreamAsync(url));
            }
        }

        public static void ToTXT(this JsonData jsonObj)
        {
            string path = Application.StartupPath + "errorLog.txt";

            if (!File.Exists(path))
                File.CreateText(path);

            File.AppendAllText(path, jsonObj.ToJsonStr() + "\r\n");
        }

        public static JsonData ToJsonData(this HttpContent content)
        {
            using (var gzipStream = new GZipStream(content.ReadAsStream(), CompressionMode.Decompress))
            {
                var outStream = new MemoryStream();
                gzipStream.CopyTo(outStream);
                return JsonMapper.ToObject(Encoding.UTF8.GetString(outStream.ToArray()));
            }
        }

        public static void ToOrderList(this JsonData jsonObj, string shopName)
        {
            int count = (int)jsonObj["data"]["total"];
            if (count > 0)
            {
                foreach (JsonData item in jsonObj["data"]["items"])
                {
                    Order order = new();
                    order._list_Products = new();
                    switch (shopName)
                    {
                        case "Normal":
                            order.id = item["id"].ToString();
                            order.preMergeFlag = item.ContainsKey("preMergeFlag") ? item["preMergeFlag"].ToString() : "";
                            //order.expressName =  "圆通";
                            //order.expressCode = "YTO";
                            break;

                        case "TAOBAO":
                            order._mallCode = item["sellerId"].ToString();
                            order._orderSn = item["tid"].ToString();
                            order._lastShipTime = null != item["expShipTime"] ? item["expShipTime"].ToString() : "已超时";
                            order._receiveName = item["receiveName"].ToString();
                            order._receiveMobile = item["receiveMobile"].ToString();
                            order._receiveCity = item["receiveCity"].ToString().Replace(",", "-");
                            order._receiveAddress = item["receiveAddress"].ToString();
                            order._remarks = string.IsNullOrEmpty(item["buyerMessage"].ToString()) ? string.IsNullOrEmpty(item["sellerMemo"].ToString()) ? "" : item["sellerMemo"].ToString() : string.IsNullOrEmpty(item["sellerMemo"].ToString()) ? item["buyerMessage"].ToString() : item["buyerMessage"].ToString() + "\r\n" + item["sellerMemo"].ToString();
                            order.expressCode = null != item["cpCode"] ? item["cpCode"].ToString() : "YTO";
                            order.expressName = order.expressCode == "YTO" ? "圆通" : order.expressCode == "STO" ? "申通" : order.expressCode == "POSTB" ? "邮政" : "圆通";
                            order.expressNo = null != item["expressNo"] ? item["expressNo"].ToString() : "";
                            order.orderStatus = item["orderStatus"].ToString();
                            foreach (JsonData P in item["orderList"])
                            {
                                order._list_Products.Add(new Products
                                {
                                    id = P["id"].ToString(),
                                    _title = P["title"].ToString(),
                                    _productId = P["numIid"].ToString(),
                                    _skuName = P["skuPropertiesName"].ToString(),
                                    _skuId = P.ContainsKey("skuId") ? P["skuId"].ToString() : P["numIid"].ToString(),
                                    _skuImg = P["picPath"].ToString(),
                                    _skuCount = (int)P["num"],
                                });
                            }
                            goto case "Normal";

                        case "PDD":
                            order._mallCode = item["mallId"].ToString();
                            order._orderSn = item["orderSn"].ToString();
                            order._lastShipTime = null != item["lastShipTime"] ? item["lastShipTime"].ToString() : "已超时";
                            order._receiveName = item["receiveName"].ToString();
                            order._receiveMobile = item["receiveMobile"].ToString();
                            order._receiveCity = item["receiveCity"].ToString();
                            order._receiveAddress = "********";
                            order._remarks = string.IsNullOrEmpty(item["buyerMemo"].ToString()) ? string.IsNullOrEmpty(item["remark"].ToString()) ? "" : item["remark"].ToString() : string.IsNullOrEmpty(item["remark"].ToString()) ? item["buyerMemo"].ToString() : item["buyerMemo"].ToString() + "\r\n" + item["remark"].ToString();
                            order.expressCode = item.ContainsKey("cpCode") ? item["cpCode"].ToString() : "YTO";
                            order.expressName = order.expressCode == "YTO" ? "圆通" : order.expressCode == "STO" ? "申通" : order.expressCode == "POSTB" ? "邮政" : "圆通";
                            order.expressNo = item.ContainsKey("trackingNumber") ? item["trackingNumber"].ToString() : "";
                            order.orderStatus = item["status"].ToString();
                            foreach (JsonData P in item["orderProducts"])
                            {
                                order._list_Products.Add(new Products
                                {
                                    id = P["id"].ToString(),
                                    _title = P["goodsName"].ToString(),
                                    _productId = P["goodsId"].ToString(),
                                    _skuName = P["goodsSpec"].ToString(),
                                    _skuId = P.ContainsKey("skuId") ? P["skuId"].ToString() : P["goodsId"].ToString(),
                                    _skuImg = P["goodsImg"].ToString(),
                                    _skuCount = (int)P["goodsCount"],
                                });
                            }
                            goto case "Normal";

                        case "KS":
                            order._mallCode = item["sellerAccountId"].ToString();
                            order._orderSn = item["orderId"].ToString();
                            order._lastShipTime = null != item["lastShipTime"] ? item["lastShipTime"].ToString() : "已超时";
                            order._receiveName = item["receiveName"].ToString();
                            order._receiveMobile = item["receiveMobile"].ToString();
                            order._receiveCity = item["receiveProvince"].ToString() + "-" + item["receiveCity"].ToString() + "-" + item["receiveDistrict"].ToString();
                            order._receiveAddress = item["receiveAddress"].ToString();
                            order._remarks = string.IsNullOrEmpty(item["buyerWords"].ToString()) ? string.IsNullOrEmpty(item["sellerWords"].ToString()) ? "" : item["sellerWords"].ToString() : string.IsNullOrEmpty(item["sellerWords"].ToString()) ? item["buyerWords"].ToString() : item["buyerWords"].ToString() + "\r\n" + item["sellerWords"].ToString();
                            order.expressCode = item.ContainsKey("cpCode") ? item["cpCode"].ToString() : "YTO";
                            order.expressName = order.expressCode == "YTO" ? "圆通" : order.expressCode == "STO" ? "申通" : order.expressCode == "POSTB" ? "邮政" : "圆通";
                            order.expressNo = item.ContainsKey("logisticsCode") ? item["logisticsCode"].ToString() : "";
                            order.orderStatus = item["orderStatus"].ToString();
                            foreach (JsonData P in item["orderProducts"])
                            {
                                order._list_Products.Add(new Products
                                {
                                    id = P["id"].ToString(),
                                    _title = P["productName"].ToString(),
                                    _productId = P["productCode"].ToString(),
                                    _skuName = P["specifications"].ToString(),
                                    _skuId = P.ContainsKey("specifications") ? P["specifications"].ToString() : "",
                                    _skuImg = P["imageUrl"].ToString(),
                                    _skuCount = (int)P["count"],
                                });
                            }
                            goto case "Normal";

                        case "LUBAN":
                            order._mallCode = item["sellerAccountId"].ToString();
                            order._orderSn = item["orderId"].ToString();
                            order._lastShipTime = null != item["expShipTime"] ? item["expShipTime"].ToString() : "已超时";
                            order._receiveName = item["postReceiver"].ToString();
                            order._receiveMobile = item["postTel"].ToString();
                            order._receiveCity = item["postProvince"].ToString() + "-" + item["postCity"].ToString() + "-" + item["postTown"].ToString();
                            order._receiveAddress = "********";
                            order._remarks = string.IsNullOrEmpty(item["buyerWords"].ToString()) ? string.IsNullOrEmpty(item["sellerWords"].ToString()) ? "" : item["sellerWords"].ToString() : string.IsNullOrEmpty(item["sellerWords"].ToString()) ? item["buyerWords"].ToString() : item["buyerWords"].ToString() + "\r\n" + item["sellerWords"].ToString();
                            order.expressCode = item.ContainsKey("cpCode") ? item["cpCode"].ToString() : "YTO";
                            order.expressName = order.expressCode == "YTO" ? "圆通" : order.expressCode == "STO" ? "申通" : order.expressCode == "POSTB" ? "邮政" : "圆通";
                            order.expressNo = item.ContainsKey("logisticsCode") ? item["logisticsCode"].ToString() : "";
                            order.orderStatus = item["orderStatus"].ToString();
                            foreach (JsonData P in item["orderProducts"])
                            {
                                order._list_Products.Add(new Products
                                {
                                    id = P["id"].ToString(),
                                    _title = P["productName"].ToString(),
                                    _productId = P["productId"].ToString(),
                                    _skuName = P["specifications"].ToString(),
                                    _skuId = P.ContainsKey("comboId") ? P["comboId"].ToString() : P["productId"].ToString(),
                                    _skuImg = P["productPic"].ToString(),
                                    _skuCount = (int)P["comboNum"],
                                });
                            }
                            goto case "Normal";

                        //---------------------------------------------------------------

                        case "禧上禧婚礼用品工厂店":
                            goto case "LUBAN";

                        case "婚庆礼品批发":
                            goto case "KS";

                        case "记得我礼品店":
                            goto case "PDD";

                        case "浅喜深爱喜品":
                            goto case "PDD";

                        case "情往礼品屋":
                            goto case "PDD";

                        case "禧来多婚庆":
                            goto case "PDD";

                        case "壹百年喜品":
                            goto case "PDD";

                        case "亿婉晴商贸":
                            goto case "TAOBAO";

                        case "liunan890312":
                            goto case "TAOBAO";
                    }
                    orderList.queue.Enqueue(order);
                }
            }
        }

        public static string ToChinese(this string str)
        {
            StringBuilder sb = new();
            foreach (char c in str)
            {
                switch (c)
                {
                    case '0':
                        sb.Append("零");
                        break;
                    case '1':
                        sb.Append("一");
                        break;
                    case '2':
                        sb.Append("二");
                        break;
                    case '3':
                        sb.Append("三");
                        break;
                    case '4':
                        sb.Append("四");
                        break;
                    case '5':
                        sb.Append("五");
                        break;
                    case '6':
                        sb.Append("六");
                        break;
                    case '7':
                        sb.Append("七");
                        break;
                    case '8':
                        sb.Append("八");
                        break;
                    case '9':
                        sb.Append("九");
                        break;
                }
            }
            return sb.ToString().Substring(sb.Length - 4);
        }

        public async static void ToRenderProductPanel(this JsonData jsonObject, View_CheckProducts view_CheckProducts, string expressNo)
        {
            string remarks = jsonObject["buyerWords"].ToString() + jsonObject["sellerWords"].ToString();
            int times = 1;
            string sysWords = string.Empty;
            string timeNow = DateTime.Now.ToString().Replace("/", "-");
            if (jsonObject.ContainsKey("sysWords"))
            {
                sysWords = jsonObject["sysWords"].ToString();
                var array = sysWords.Split('|');
                times += array.Length;
                view_CheckProducts.labCheckTime.Items.AddRange(array);
            }
            Controller.CtlFactory("SetSysWords", [jsonObject["id"], jsonObject["sysOrderId"], jsonObject["orderId"], sysWords + timeNow + "|"]);

            view_CheckProducts.labRemarks.Text += remarks;
            view_CheckProducts.btnRemarks.Symbol = view_CheckProducts.labRemarks.Text.Length > 0 ? 361453 : 361452;
            view_CheckProducts.labCheckCount.IntValue = times;
            view_CheckProducts.labCheckTime.Text = timeNow;
            Controller.canCheckNext = view_CheckProducts.labRemarks.Text.Length > 0 ? false : true;

            string province = jsonObject["receiveProvince"].ToString();
            if (province.Contains("甘肃") || province.Contains("宁夏") || province.Contains("青海"))  Controller.view_MainForm.btnWeight.BeginInvoke(() => { Controller.view_MainForm.btnWeight.Text = "3.0"; });  

            Controller.view_MainForm.pnlBody.BeginInvoke(() =>
            {
                Controller.view_MainForm.btnMutilPackage.Text = expressNo;
                Controller.view_MainForm.pnlBody.Controls.Add(view_CheckProducts);

            });
        }
        public async static Task ToRenderProduct(this JsonData items, View_CheckProducts view_CheckProducts)
        {
            foreach (JsonData i in items)
            {
                string skuid = i["skuId"].ToString();
                var product = view_CheckProducts.GetProduct(skuid);
                if (product.skuId == skuid)
                {
                    product.lab_count.Text = (int.Parse(product.lab_count.Text) + (int)i["productNumber"]).ToString();
                }
                else
                {
                    view_CheckProducts.pnlContent.Add(product);
                    product.skuId = skuid;
                    product.lab_count.Text = i["productNumber"].ToString();
                    product.lab_skuName.Text = i["productSpecDesc"].ToString();
                    product.lab_title.Text = i["productName"].ToString();
                    product.img.Image = await i["productPic"].ToString().ToImage();
                }
            }

        }

        public static View_CheckProducts_Products GetProduct(this View_CheckProducts view_CheckProducts, string skiuId)
        {
            var product = view_CheckProducts.erpProducts.Find(p => p.skuId == skiuId);
            if (null != product) return product;

            if (view_CheckProducts.currentIndex == view_CheckProducts.erpProducts.Count)
            {
                product = new View_CheckProducts_Products();
                view_CheckProducts.erpProducts.Add(product);
                view_CheckProducts.currentIndex++;
                return product;
            }
            else
            {
                product = view_CheckProducts.erpProducts[view_CheckProducts.currentIndex];
                view_CheckProducts.currentIndex++;
                return product;
            }

        }
    }

}
